/**
 * 
 */
package neptune.web.server.services;

import java.util.ArrayList;
import java.util.Iterator;

import neptune.manager.IsUser;
import neptune.manager.model.ApplicationProperties;
import neptune.manager.model.cluster.Cluster;
import neptune.manager.model.cluster.PCU;
import neptune.manager.model.cluster.PhysicalNode;
import neptune.manager.model.experiment.Experiment;
import neptune.manager.model.experiment.ExperimentState;
import neptune.manager.model.template.VmTemplate;
import neptune.manager.model.topology.Cpu;
import neptune.manager.model.topology.DuplicatedNodeException;
import neptune.manager.model.topology.EndPoint;
import neptune.manager.model.topology.Hypervisor;
import neptune.manager.model.topology.IPAddress;
import neptune.manager.model.topology.Link;
import neptune.manager.model.topology.LinkException;
import neptune.manager.model.topology.MACAddress;
import neptune.manager.model.topology.NetworkInterface;
import neptune.manager.model.topology.Node;
import neptune.manager.model.topology.NotEnoughResourcesException;
import neptune.manager.model.topology.OLPIEndPoint;
import neptune.manager.model.topology.OperativeSystem;
import neptune.manager.model.topology.Property;
import neptune.manager.model.topology.Software;
import neptune.manager.model.topology.Topology;
import neptune.manager.utils.IllegalValueException;
import neptune.web.client.model.SerializableApplicationProperties;
import neptune.web.client.model.SerializableExperiment;
import neptune.web.client.model.SerializableExperimentState;
import neptune.web.client.model.SerializableUser;
import neptune.web.client.model.SerializableVmTemplate;
import neptune.web.client.model.cluster.SerializableCluster;
import neptune.web.client.model.cluster.SerializablePCU;
import neptune.web.client.model.cluster.SerializablePhysicalNode;
import neptune.web.client.model.topology.SerializableCpu;
import neptune.web.client.model.topology.SerializableEndPoint;
import neptune.web.client.model.topology.SerializableHypervisor;
import neptune.web.client.model.topology.SerializableIPAddress;
import neptune.web.client.model.topology.SerializableLink;
import neptune.web.client.model.topology.SerializableMACAddress;
import neptune.web.client.model.topology.SerializableNetworkInterface;
import neptune.web.client.model.topology.SerializableNode;
import neptune.web.client.model.topology.SerializableOLPIEndPoint;
import neptune.web.client.model.topology.SerializableOperativeSystem;
import neptune.web.client.model.topology.SerializableProperty;
import neptune.web.client.model.topology.SerializableSoftware;
import neptune.web.client.model.topology.SerializableTopology;
import neptune.web.server.model.ApplicationUser;

/**
 * Metodi di utilita' per la conversione fra tipi Serializable e tipo gestiti da
 * NeptuneManager. Questi metodi sono necessari poiche' GWT tramuta il Java dal
 * lato client in Javascript, quindi, non e' possibile adoperare le stesse
 * classi ed e' necessaria una conversione.
 * 
 * @author Roberto Bifulco [info@robertobifulco.it, robertobifulco.it]
 * @author Luigi Lorenzo Arpino [luigiarpino@yahoo.it]
 * 
 */
public class SerializationHelper {
	public static ApplicationProperties toApplicationProperties(
			SerializableApplicationProperties serAppProp) {
		ApplicationProperties appProp = new ApplicationProperties();
		appProp.setVmTemplatesDir(serAppProp.getVmTemplatesDir());
		appProp.setExperimentsVMsDir(serAppProp.getExperimentsVMsDir());
		//
		appProp.setIsDebug(serAppProp.getIsDebug());
		//
		appProp.setNetmaskControlIpRange(serAppProp.getNetmaskControlIpRange());
		appProp.setStartIpControlIpRange(serAppProp.getStartIpControlIpRange());
		appProp.setEndIpControlIpRange(serAppProp.getEndIpControlIpRange());
		appProp.setGatewayControlIpRange(serAppProp.getGatewayControlIpRange());
		//
		appProp.setAddressClusterSubnet(serAppProp.getAddressClusterSubnet());
		appProp.setNetmaskClusterSubnet(serAppProp.getNetmaskClusterSubnet());
		//
		appProp.setBaseAddressExperimentSubnet(serAppProp
				.getBaseAddressExperimentSubnet());
		appProp.setNetmaskExperimentSubnet(serAppProp
				.getNetmaskExperimentSubnet());
		//
		appProp.setNetmaskLinkSubnet(serAppProp.getNetmaskLinkSubnet());
		return appProp;
	}

	public static ApplicationUser toApplicationUser(SerializableUser user) {
		if (user == null)
			return null;

		ApplicationUser appUser = new ApplicationUser(false, user.getRole(),
				user.getUsername());
		appUser.setPassword(user.getPassword());
		appUser.setEmail(user.getEmail());

		return appUser;
	}

	public static Cpu toCpu(SerializableCpu serCpu) {
		if (serCpu == null)
			return null;

		return new Cpu(serCpu.getName(), serCpu.getType(), serCpu.getClock(),
				serCpu.getAmount());
	}

	public static EndPoint toEndPoint(SerializableEndPoint serEP) {
		if (serEP == null)
			return null;

		if (serEP instanceof SerializableOLPIEndPoint) {
			OLPIEndPoint ep = new OLPIEndPoint(serEP.getNodeId(), serEP
					.getInterfaceId());

			return ep;
		}

		return null;
	}

	public static Hypervisor toHypervisor(SerializableHypervisor serHypervisor) {
		Hypervisor hypervisor = new Hypervisor();
		if (serHypervisor != null) {
			hypervisor.setType(serHypervisor.getType());
			hypervisor.setVersion(serHypervisor.getVersion());
		}

		return hypervisor;
	}

	public static IPAddress toIpAddress(SerializableIPAddress serIpAddr)
			throws IllegalValueException {
		if (serIpAddr == null)
			return null;

		return new IPAddress(serIpAddr.getVersion(), serIpAddr.getAddress(),
				serIpAddr.getSubnetMask(), serIpAddr.isControlAddress());
	}

	public static Link toLink(SerializableLink serLink) {
		Link link = new Link(serLink.getId(), toEndPoint(serLink.getSource()),
				toEndPoint(serLink.getDestination()), serLink.isFullDuplex());

		for (SerializableProperty serProp : serLink.getProperties()) {
			Property prop = toProperty(serProp);
			if (prop != null)
				link.addProperty(prop);
		}

		return link;
	}

	public static MACAddress toMacAddress(SerializableMACAddress macAddress) {
		if (macAddress == null)
			return null;

		return new MACAddress(macAddress.getAddress());
	}

	public static NetworkInterface toNetworkInterface(
			SerializableNetworkInterface serInterface)
			throws IllegalValueException {
		if (serInterface == null)
			return null;

		NetworkInterface netIf = new NetworkInterface(serInterface
				.getInterfaceName(), serInterface.getBindingDescription(),
				toMacAddress(serInterface.getMacAddress()));
		netIf.setParentNode(serInterface.getParentNode());

		for (SerializableIPAddress serIpAddr : serInterface.getIpAddresses()) {
			IPAddress ipAddr = toIpAddress(serIpAddr);
			if (ipAddr != null)
				netIf.addIpAddress(ipAddr);
		}

		netIf.setType(serInterface.getType());

		return netIf;
	}

	public static Node toNode(SerializableNode serNode, Topology topology)
			throws NotEnoughResourcesException, IllegalValueException {

		Node node = new Node(serNode.getDescription(), serNode.getId(), serNode
				.getName());
		node.setCpu(toCpu(serNode.getCpu()));
		node.setRam(serNode.getRam());
		node.setHd(serNode.getHd());

		for (SerializableNetworkInterface serInterface : serNode
				.getInterfaces()) {
			node.addNetworkInterface(toNetworkInterface(serInterface));
		}

		node
				.setOperativeSystem(toOperativeSystem(serNode
						.getOperativeSystem()));
		node.setSoftwareTemplate(serNode.getSoftwareTemplate());

		for (SerializableSoftware serSoftware : serNode.getInstalledSoftwares()) {
			node.addSoftware(toSoftware(serSoftware));
		}

		node.setHypervisor(toHypervisor(serNode.getHypervisor()));

		for (String serHostedNode : serNode.getHostedNodes()) {
			node.addHostedNode(topology.searchNodeIntoTopology(serHostedNode));
		}

		node.setVirtual(serNode.isVirtual());
		node.setHoster(topology.searchNodeIntoTopology(serNode.getHosterId()));
		node.setControlPort(serNode.getControlPort());

		return node;
	}

	public static OperativeSystem toOperativeSystem(
			SerializableOperativeSystem serOperativeSystem) {
		if (serOperativeSystem == null)
			return null;

		return new OperativeSystem(serOperativeSystem.getName(),
				serOperativeSystem.getVersion(), serOperativeSystem
						.getAdminUsername(), serOperativeSystem
						.getAdminPassword());
	}

	public static PhysicalNode toPhysicalNode(
			SerializablePhysicalNode sPhysicalNode)
			throws IllegalValueException {
		PhysicalNode physicalNode = new PhysicalNode(sPhysicalNode
				.getDescription(), sPhysicalNode.getId(), sPhysicalNode
				.getName());
		physicalNode.setControlPort(sPhysicalNode.getControlPort());
		physicalNode.setCpu(toCpu(sPhysicalNode.getCpu()));
		physicalNode.setDescription(sPhysicalNode.getDescription());
		physicalNode.setHd(sPhysicalNode.getHd());
		physicalNode.setHostedNodes(sPhysicalNode.getHostedNodes());
		// physicalNode.setHoster(sPhysicalNode.getH)
		physicalNode.setHypervisor(SerializationHelper
				.toHypervisor(sPhysicalNode.getHypervisor()));
		physicalNode.setId(sPhysicalNode.getId());
		physicalNode.setOperativeSystem(SerializationHelper
				.toOperativeSystem(sPhysicalNode.getOperativeSystem()));
		for (SerializableNetworkInterface serialNetInt : sPhysicalNode
				.getInterfaces()) {
			physicalNode.addNetworkInterface(toNetworkInterface(serialNetInt));
		}
		// physicalNode.setPcu(pcu);
		physicalNode.setRam(sPhysicalNode.getRam());
		physicalNode.setSoftwareTemplate(sPhysicalNode.getSoftwareTemplate());
		// physicalNode.setVirtual(false);

		return physicalNode;

	}

	public static Property toProperty(SerializableProperty serProp) {
		if (serProp == null)
			return null;
		return new Property(serProp.getName(), serProp.getValue());
	}

	public static SerializableApplicationProperties toSerializableApplicationProperties(
			ApplicationProperties appProp) {
		SerializableApplicationProperties serAppProp = new SerializableApplicationProperties();
		serAppProp.setVmTemplatesDir(appProp.getVmTemplatesDir());
		serAppProp.setExperimentsVMsDir(appProp.getExperimentsVMsDir());
		//
		serAppProp.setIsDebug(appProp.isDebug());
		//
		serAppProp.setNetmaskControlIpRange(appProp.getNetmaskControlIpRange());
		serAppProp.setStartIpControlIpRange(appProp.getStartIpControlIpRange());
		serAppProp.setEndIpControlIpRange(appProp.getEndIpControlIpRange());
		serAppProp.setGatewayControlIpRange(appProp.getGatewayControlIpRange());
		//
		serAppProp.setAddressClusterSubnet(appProp.getAddressClusterSubnet());
		serAppProp.setNetmaskClusterSubnet(appProp.getNetmaskClusterSubnet());
		//
		serAppProp.setBaseAddressExperimentSubnet(appProp
				.getBaseAddressExperimentSubnet());
		serAppProp.setNetmaskExperimentSubnet(appProp
				.getNetmaskExperimentSubnet());
		//
		serAppProp.setNetmaskLinkSubnet(appProp.getNetmaskLinkSubnet());
		return serAppProp;
	}

	public static SerializableCluster toSerializableCluster(Cluster cluster) {
		SerializableCluster serCluster = new SerializableCluster();

		serCluster.setControlNetAddress(toSerializableIPAddress(cluster
				.getControlNetAddress()));

		ArrayList<SerializablePhysicalNode> phyNodes = new ArrayList<SerializablePhysicalNode>(
				0);
		if (cluster.getNodes() != null) {
			for (PhysicalNode node : cluster.getNodes()) {
				phyNodes.add(toSerializablePhysicalNode(node));
			}
			serCluster.setNodes(phyNodes);
		}
		return serCluster;
	}

	public static SerializableCpu toSerializableCpu(Cpu cpu) {
		if (cpu == null)
			return null;

		SerializableCpu serCpu = new SerializableCpu();

		serCpu.setClock(cpu.getClock());
		serCpu.setName(cpu.getName());
		serCpu.setType(cpu.getType());
		serCpu.setAmount(cpu.getAmount());

		return serCpu;
	}

	public static SerializableEndPoint toSerializableEndPoint(EndPoint source) {
		if (source == null)
			return null;

		if (source instanceof OLPIEndPoint) {
			SerializableOLPIEndPoint serEP = new SerializableOLPIEndPoint();
			serEP.setInterfaceId(source.getInterfaceId());
			serEP.setNodeId(source.getNodeId());

			return serEP;
		} else {
			SerializableEndPoint serEP = new SerializableEndPoint();
			serEP.setInterfaceId(source.getInterfaceId());
			serEP.setNodeId(source.getNodeId());

			return serEP;
		}
	}

	public static SerializableExperiment toSerializableExperiment(Experiment exp) {
		if (exp == null)
			return null;

		SerializableExperiment serExp = new SerializableExperiment();

		serExp.setExperimentId(exp.getExperimentId());
		serExp.setAdministrator(exp.getAdministrator());
		serExp.setAssignedSubnet(toSerializableIPAddress(exp
				.getAssignedSubnet()));

		// Serializza gli utenti (c'e' un passaggio dall'oggetto IsUser, al
		// semplice tipo String)
		ArrayList<String> serSuperUsers = serExp.getPrivilegedUsers();
		for (Iterator<IsUser> iterator = exp.getPrivilegedUserList().iterator(); iterator
				.hasNext();) {
			IsUser user = (IsUser) iterator.next();
			serSuperUsers.add(user.getUsername());
		}
		ArrayList<String> serUsers = serExp.getUsers();
		for (Iterator<IsUser> iterator = exp.getUserList().iterator(); iterator
				.hasNext();) {
			IsUser user = (IsUser) iterator.next();
			serUsers.add(user.getUsername());
		}

		// Serializza lo stato
		serExp.setState(toSerializableExperimentState(exp.getState()));

		serExp.setTopology(toSerializableTopology(exp.getTopology()));

		return serExp;
	}

	public static SerializableExperimentState toSerializableExperimentState(
			ExperimentState state) {
		if (state == null)
			return null;

		SerializableExperimentState serState = new SerializableExperimentState();

		serState.setState(state.getValue());
		serState.setCreationTimestamp(state.getCreationTimestamp());
		serState.setStartTimestamp(state.getStartTimestamp());
		serState.setStopTimestamp(state.getStopTimestamp());
		serState.setTotalExecutionTime(state.getTotalExecutionTime());

		return serState;
	}

	public static SerializableHypervisor toSerializableHypervisor(
			Hypervisor hypervisor) {
		if (hypervisor == null)
			return null;

		SerializableHypervisor serHyp = new SerializableHypervisor();

		serHyp.setType(hypervisor.getType());
		serHyp.setVersion(hypervisor.getVersion());

		return serHyp;
	}

	public static SerializableIPAddress toSerializableIPAddress(
			IPAddress ipAddress) {
		if (ipAddress == null)
			return null;

		SerializableIPAddress serIP = new SerializableIPAddress();

		serIP.setAddress(ipAddress.getAddress());
		serIP.setControlAddress(ipAddress.isControlAddress());
		serIP.setSubnetMask(ipAddress.getSubnetMask());
		serIP.setVersion(ipAddress.getVersion());

		return serIP;
	}

	public static SerializableLink toSerializableLink(Link link) {
		if (link == null)
			return null;

		SerializableLink serLink = new SerializableLink();

		serLink.setSource(toSerializableEndPoint(link.getSource()));
		serLink.setDestination(toSerializableEndPoint(link.getDestination()));
		serLink.setId(link.getId());
		serLink.setFullDuplex(link.isFullDuplex());

		Property[] properties = link.getProperties();
		ArrayList<SerializableProperty> serProperties = new ArrayList<SerializableProperty>(
				0);
		for (int i = 0; i < properties.length; i++) {
			SerializableProperty serProp = toSerializableProperty(properties[i]);
			if (serProp != null)
				serProperties.add(serProp);
		}
		serLink.setProperties(serProperties);

		return serLink;
	}

	public static SerializableMACAddress toSerializableMACAddress(
			MACAddress macAddress) {
		if (macAddress == null)
			return null;

		SerializableMACAddress serMAC = new SerializableMACAddress();

		serMAC.setAddress(macAddress.getAddress());

		return serMAC;
	}

	public static SerializableNetworkInterface toSerializableNetworkInterface(
			NetworkInterface networkInterface) {
		if (networkInterface == null)
			return null;

		SerializableNetworkInterface serNI = new SerializableNetworkInterface();

		serNI.setBindingDescription(networkInterface.getBindingDescription());
		serNI.setControlAddress(toSerializableIPAddress(networkInterface
				.getControlAddress()));
		serNI.setInterfaceName(networkInterface.getInterfaceName());
		serNI.setParentNode(networkInterface.getParentNode());

		IPAddress[] ipAddresses = networkInterface.getIpAddresses();
		ArrayList<SerializableIPAddress> serIpAddresses = new ArrayList<SerializableIPAddress>(
				0);
		for (int i = 0; i < ipAddresses.length; i++) {
			SerializableIPAddress serIpAddr = toSerializableIPAddress(ipAddresses[i]);
			if (serIpAddr != null)
				serIpAddresses.add(serIpAddr);
		}
		serNI.setIpAddresses(serIpAddresses);

		serNI.setMacAddress(toSerializableMACAddress(networkInterface
				.getMacAddress()));
		serNI.setType(networkInterface.getType());

		return serNI;
	}

	public static SerializableNode toSerializableNode(Node node) {
		if (node == null)
			return null;

		SerializableNode serNode = new SerializableNode();

		serNode.setDescription(node.getDescription());
		serNode.setId(node.getId());
		serNode.setName(node.getName());
		serNode.setCpu(toSerializableCpu(node.getCpu()));
		serNode.setRam(node.getRam());
		serNode.setHd(node.getHd());

		NetworkInterface[] interfaces = node.getInterfaces();
		ArrayList<SerializableNetworkInterface> serInterfaces = new ArrayList<SerializableNetworkInterface>(
				0);
		for (int i = 0; i < interfaces.length; i++) {
			SerializableNetworkInterface serNetIf = toSerializableNetworkInterface(interfaces[i]);
			if (serNetIf != null)
				serInterfaces.add(serNetIf);
		}
		serNode.setInterfaces(serInterfaces);

		serNode.setOperativeSystem(toSerializableOperativeSystem(node
				.getOperativeSystem()));
		serNode.setSoftwareTemplate(node.getSoftwareTemplate());

		Software[] softwares = node.getInstalledSoftwares();
		ArrayList<SerializableSoftware> serSoftwares = new ArrayList<SerializableSoftware>(
				0);
		for (int i = 0; i < softwares.length; i++)
			serSoftwares.add(toSerializableSoftware(softwares[i]));
		serNode.setInstalledSoftwares(serSoftwares);

		serNode.setHypervisor(toSerializableHypervisor(node.getHypervisor()));

		String[] hostedNodes = node.getHostedNodes();
		ArrayList<String> serHostedNodes = new ArrayList<String>(0);
		for (int i = 0; i < hostedNodes.length; i++)
			serHostedNodes.add(hostedNodes[i]);
		serNode.setHostedNodes(serHostedNodes);

		serNode.setVirtual(node.isVirtual());
		serNode.setHosterId(node.getHoster() != null ? node.getHoster().getId()
				: "");
		serNode.setControlPort(node.getControlPort());

		return serNode;
	}

	public static SerializableOperativeSystem toSerializableOperativeSystem(
			OperativeSystem operativeSystem) {
		if (operativeSystem == null)
			return null;

		SerializableOperativeSystem serOS = new SerializableOperativeSystem();

		serOS.setAdminPassword(operativeSystem.getAdminPassword());
		serOS.setAdminUsername(operativeSystem.getAdminUsername());
		serOS.setName(operativeSystem.getName());
		serOS.setVersion(operativeSystem.getVersion());

		return serOS;
	}

	public static SerializablePCU toSerializablePCU(PCU pcu) {
		if (pcu == null)
			return null;
		SerializablePCU serPCU = new SerializablePCU();

		serPCU.setIpAddress(toSerializableIPAddress(pcu.getIpAddress()));
		serPCU.setPassword(pcu.getPassword());
		serPCU.setType(pcu.getType());
		serPCU.setUsername(pcu.getUsername());

		return serPCU;
	}

	public static SerializablePhysicalNode toSerializablePhysicalNode(
			PhysicalNode node) {

		SerializablePhysicalNode serPhyNode = new SerializablePhysicalNode();

		SerializableNode serNode = toSerializableNode(node);

		serPhyNode.setControlPort(serNode.getControlPort());
		serPhyNode.setCpu(serNode.getCpu());
		serPhyNode.setDescription(serNode.getDescription());
		serPhyNode.setHd(serNode.getHd());
		// TODO come gestire gli hosted nodes?
		serPhyNode.setHostedNodes(serNode.getHostedNodes());
		serPhyNode.setHypervisor(serNode.getHypervisor());
		serPhyNode.setId(serNode.getId());
		serPhyNode.setName(serNode.getName());
		serPhyNode.setInstalledSoftwares(serNode.getInstalledSoftwares());
		serPhyNode.setInterfaces(serNode.getInterfaces());
		serPhyNode.setOperativeSystem(serNode.getOperativeSystem());
		serPhyNode.setPcu(toSerializablePCU(node.getPcu()));
		serPhyNode.setRam(serNode.getRam());
		serPhyNode.setSoftwareTemplate(serNode.getSoftwareTemplate());
		serPhyNode.setVirtual(false);

		return serPhyNode;
	}

	public static SerializableProperty toSerializableProperty(Property property) {
		if (property == null)
			return null;

		SerializableProperty serProp = new SerializableProperty();

		serProp.setName(property.getName());
		serProp.setValue(property.getValue());

		return serProp;
	}

	public static SerializableSoftware toSerializableSoftware(Software software) {
		if (software == null)
			return null;

		SerializableSoftware serSoft = new SerializableSoftware();

		serSoft.setId(software.getId());
		serSoft.setType(software.getType());
		serSoft.setVersion(software.getVersion());

		return serSoft;
	}

	public static SerializableTopology toSerializableTopology(Topology topology) {
		if (topology == null)
			return null;

		SerializableTopology serTopology = new SerializableTopology();
		serTopology.setName(topology.getName());
		serTopology.setDescription(topology.getDescription());

		Node[] nodes = topology.getNodes();
		Link[] links = topology.getLinks();

		ArrayList<SerializableNode> serNodes = new ArrayList<SerializableNode>(
				0);
		ArrayList<SerializableLink> serLinks = new ArrayList<SerializableLink>(
				0);

		for (int i = 0; i < nodes.length; i++) {
			SerializableNode serNode = toSerializableNode(nodes[i]);
			if (serNode != null)
				serNodes.add(serNode);
		}
		for (int i = 0; i < links.length; i++) {
			SerializableLink serLink = toSerializableLink(links[i]);
			if (serLink != null)
				serLinks.add(serLink);
		}

		serTopology.setNodes(serNodes);
		serTopology.setLinks(serLinks);
		serTopology.setName(topology.getName());

		return serTopology;
	}

	public static SerializableUser toSerializableUser(ApplicationUser user) {
		if (user == null)
			return null;

		SerializableUser serUser = new SerializableUser();

		serUser.setUsername(user.getId());
		serUser.setPassword(user.getPassword());
		serUser.setEmail(user.getEmail());
		serUser.setRole(user.getRole());

		return serUser;
	}

	public static SerializableUser[] toSerializableUser(ApplicationUser[] users) {
		if (users == null)
			return null;

		SerializableUser[] serUsers = new SerializableUser[users.length];

		for (int i = 0; i < serUsers.length; i++) {
			serUsers[i] = toSerializableUser(users[i]);
		}

		return serUsers;
	}

	public static SerializableVmTemplate toSerializableVmTemplate(
			VmTemplate vmTemplate) {

		SerializableVmTemplate serVmTemp = new SerializableVmTemplate();

		serVmTemp.setId(vmTemplate.getId());
		serVmTemp.setOs(toSerializableOperativeSystem(vmTemplate
				.getOperativeSystem()));

		ArrayList<SerializableSoftware> serSws = new ArrayList<SerializableSoftware>(
				0);
		for (Software software : vmTemplate.getSoftwares()) {
			serSws.add(toSerializableSoftware(software));
		}
		serVmTemp.setSws(serSws);

		serVmTemp.setControlPort(vmTemplate.getControlPort());

		return serVmTemp;
	}

	public static Software toSoftware(SerializableSoftware serSoftware) {
		if (serSoftware == null)
			return null;
		return new Software(serSoftware.getId(), serSoftware.getVersion(),
				serSoftware.getType());
	}

	/**
	 * Effettua la deserializzazione di una topologia. Al contempo, nel creare
	 * l'oggetto della classe Topology, verifica che tutti i vincoli di
	 * definizione di una topologia siano rispettati. In caso contrario solleva
	 * un'eccezione.
	 * 
	 * @param serTopology
	 * @return
	 * @throws TopologyDefinitionException
	 */
	public static Topology toTopology(SerializableTopology serTopology)
			throws TopologyDefinitionException {
		boolean error = false;
		String errorMessage = "";
		Topology topology = new Topology();

		topology.setName(serTopology.getName());
		topology.setDescription(serTopology.getDescription());

		for (SerializableNode serNode : serTopology.getNodes()) {
			try {
				topology.addNode(toNode(serNode, topology));
			} catch (DuplicatedNodeException e) {
				error = true;
				errorMessage += e.getMessage() + "\n";
			} catch (NotEnoughResourcesException e) {
				error = true;
				errorMessage += e.getMessage() + "\n";
			} catch (IllegalValueException e) {
				error = true;
				errorMessage += "Node '" + serNode.getId()
						+ "' definition error:" + e.getMessage() + "\n";
			}
		}
		for (SerializableLink serLink : serTopology.getLinks()) {
			try {
				topology.addLink(toLink(serLink));
			} catch (LinkException e) {
				error = true;
				errorMessage += e.getMessage() + "\n";
			}
		}

		if (error)
			throw new TopologyDefinitionException(errorMessage);

		return topology;
	}
}
